cc.Class({
    extends: cc.Component,

    properties: {
        itemTemplate: cc.Prefab,
        itemHeight: 0,
        itemSpace:0,
        updateItemEvent: cc.Component.EventHandler,

        spawnCount: {
            default: 0,
            visible: false,
        },
        totalCount: {
            default: 0,
            visible: false,
        },
        _items: [],
        _kAddSpawnCount: 2,
    },
    editor: {
        menu: 'ExtendUI/ListView',
        requireComponent: cc.ScrollView,
    },

    init: function (totalCount) {
        this.content = this.getComponent(cc.ScrollView).content;
        this.scrollView = this.getComponent(cc.ScrollView);
        var _totalCount = totalCount !== null && totalCount !== undefined ? totalCount : this.totalCount; // 兼容不传入totalCount的旧接口
        // 错误提示
        if (!this._errTips()) return;
        // 初始化需要交换的数量
        this.initSpawnCount();
        // 删除所有item
        this.removeAllItem();
        // 设置内容高度
        this.content.height = this.itemHeight * _totalCount;
        // 初始化内容位置
        this.initContentPos();
        // 设置总个数
        this.setTotalCount(_totalCount);
        // 刷新当前所有item
        this.updateAllItem();
    },
    // 删除所有item
    removeAllItem: function() {
        for (var i = 0; i < this._items.length; i++) {
            this._items[i].destroy();
        }
        this._items = [];
    },
    // 初始化内容位置
    initContentPos: function() {
        this.content.y = this.node.height/2;
        this._isDown = null;
    },
    // 初始化复用item的数量
    initSpawnCount: function() {
        this.spawnCount = Math.ceil(this.node.height / this.itemHeight) + this._kAddSpawnCount;
    },
    // 设置总个数
    setTotalCount: function(totalCount) {
        if (totalCount === null || totalCount === undefined) return;
        this.totalCount = totalCount;
        // 设置内容高度
        this.content.height = this.itemHeight  * this.totalCount;
        // 创建item
        var spawnCount = this.spawnCount < this.totalCount ? this.spawnCount : this.totalCount;
        if (this._items.length <= spawnCount) {
            for (var i = this._items.length; i < spawnCount; ++i) {
                this._newItem(i);
            }
        }
        else {
            for (var i = spawnCount; i < this._items.length; ++i) {
                // cc.logEx('ListView_destroyItem', i);
                this._items[i].destroy();
            }
        }
    },
    // 刷新当前所有item
    updateAllItem: function() {
        var spawnCount = this.spawnCount < this.totalCount ? this.spawnCount : this.totalCount;
        var initY = this.content.parent.height*(1-this.content.parent.anchorY);
        var initIndex = Math.floor((this.content.y - initY) / this.itemHeight);
        // cc.logEx('initIndex', initIndex);
        if (initIndex < 0) initIndex = 0;
        if (initIndex > spawnCount + this.totalCount) initIndex = spawnCount + this.totalCount;
        if (this._isDown) {
            initIndex -= this._kAddSpawnCount;
        }
        this._items.sort((item1, item2) => item1.itemID - item2.itemID);
        for (var i = 0; i < this._items.length; i++) {
            var item = this._items[i];
            // cc.logEx('updateAllItem', item.itemID, initIndex + i);
            this.onItemData(item, initIndex + i);
        }
    },


    _errTips: function() {
        if (this.itemHeight === 0) {
            cc.error('错误：ListView未设置itemHeight', this.itemHeight);
            return false;
        }
        if (this.content.getComponent(cc.Layout)) {
            cc.error('错误：ListView的content中不能有Layout组件');
            return false;
        }
        return true;
    },

    _newItem: function(i) {
        // cc.logEx('ListView_newItem', i);
        var item = this.itemTemplate.newTo(this.content);
        item.y = -item.height * i;
        item.itemID = i;
        this._items.push(item);
    },

    start: function() {
        this._updateTimer = 0;
        this._updateInterval = 0.1;
        this._lastContentPosY = 0; // use this variable to detect if we are scrolling up or down
    },
    update: function(dt) {
        this._updateTimer += dt;
        if (this._updateTimer < this._updateInterval) return;
        this._updateTimer = 0;

        if (!this.content || this.content.y === this._lastContentPosY) return;

        var items = this._items;
        this._isDown = this.content.y < this._lastContentPosY;
        var offset = this.itemHeight * items.length;
        for (var i = 0; i < items.length; ++i) {
            var viewPos = this.getPositionInView(items[i]);
            if (this._isDown) {
                if (viewPos.y < -this.node.height/2) {
                    if (items[i].y + offset < this.itemHeight) {
                        items[i].y = items[i].y + offset;
                        items[i].itemID += -items.length;
                        // cc.logEx('onDownItemData', items[i].itemID);
                        this.onItemData(items[i], items[i].itemID);
                    }
                }
            } else {
                if (viewPos.y > this.node.height/2 + this.itemHeight) {
                    if (items[i].y - offset > -this.content.height) {
                        items[i].y = items[i].y - offset ;
                        items[i].itemID += items.length;
                        // cc.logEx('onUpItemData', items[i].itemID);
                        this.onItemData(items[i], items[i].itemID);
                    }
                }
            }
        }
        // update _lastContentPosY
        this._lastContentPosY = this.content.y;
    },
    getPositionInView: function (item) {
        var worldPos = item.parent.convertToWorldSpaceAR(item.position);
        var viewPos = this.node.convertToNodeSpaceAR(worldPos);
        return viewPos;
    },

    onItemData: function(item, i) {
        if (i >= 0 && i < this.totalCount) {
            this.updateItemEvent.emit([item, i,this.scrollView]);
        }
    }
});